﻿//*** Guidance generated code ***//
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Linq.Expressions;

using NHibernate;
using NHibernate.Criterion;

using ProjectBase.Core;

namespace $safeprojectname$
{
    public static partial class DaoExtensions
    {
        /// <summary>
        ///     Parameter 'expr' should be like '() => filter.User'.
        ///     If e.g. the 'User' reference exists new Criteria is added,
        ///     to filter the list with the provided referenced entity.
        ///     Same as the 'new SimpleExpression("User", filter.User, "=", false))'
        /// </summary>
        public static IList<ICriterion> AddEqual<TFilter, TResult>(this IList<ICriterion> criteria, TFilter filter
            , Expression<Func<TFilter, TResult>> expr, TResult value = null)
            where TFilter : Core.IFilter
            where TResult : class, IPersistentObject
        {
            MemberExpression body;
            switch (expr.Body.NodeType)
            {
                case ExpressionType.MemberAccess: // e.g. entity.User
                    body = expr.Body as MemberExpression;
                    break;

                default:
                    throw new NotSupportedException(
                        "Provided 'Expression<Func<TFilter, TResult>> expr' parameter must be of a 'ExpressionType.MemberAccess'. ");
            }

            if (value.IsNull())
            {
                var result = GetCompiled(expr);
                try
                {
                    value = result(filter);
                    if (value.IsNull()) // the filtered value is null, no need to append this criteria
                    {
                        return criteria;
                    }
                }
                catch (NullReferenceException) { }
            }

            if (value.Is())
            {
                criteria.Add
                (
                    new SimpleExpression(body.Member.Name, value, Const.Signs[Sign.Equal], false)
                );
            }
            return criteria;
        }

        public static IList<ICriterion> AddNotEqual<TFilter, TResult>(this IList<ICriterion> criteria, TFilter filter
            , Expression<Func<TFilter, TResult>> expr, TResult value = null)
            where TFilter : Core.IFilter
            where TResult : class, IPersistentObject
        {
            if (value.IsNull()) // the filtered value is null, no need to append this criteria
            {
                return criteria;
            }

            MemberExpression body;
            switch (expr.Body.NodeType)
            {
                case ExpressionType.MemberAccess: // e.g. entity.User
                    body = expr.Body as MemberExpression;
                    break;

                default:
                    throw new NotSupportedException(
                        "Provided 'Expression<Func<TFilter, TResult>> expr' parameter must be of a 'ExpressionType.MemberAccess'. ");
            }

            if (value.IsNull())
            {
                var result = GetCompiled(expr);
                try
                {
                    value = result(filter);
                    if (value.IsNull()) // the filtered value is null, no need to append this criteria
                    {
                        return criteria;
                    }
                }
                catch (NullReferenceException) { }
            }

            if (value.Is())
            {
                criteria.Add
                (
                    new NotExpression
                    (
                        new SimpleExpression(body.Member.Name, value, Const.Signs[Sign.Equal], false)
                    )
                );
            }

            return criteria;
        }
    }
}